package com.coldchain.cys.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.coldchain.common.auth.AuthUser;
import com.coldchain.common.msg.BaseResponse;
import com.coldchain.common.msg.ObjectRestResponse;
import com.coldchain.common.redis.RedisUtils;
import com.coldchain.common.util.DesUtil;
import com.coldchain.common.util.MD5Utils;
import com.coldchain.common.util.RandomUtil;
import com.coldchain.common.validator.ValidatorUtils;
import com.coldchain.cys.constant.Constant;
import com.coldchain.cys.context.CysContext;
import com.coldchain.cys.entity.CarDriver;
import com.coldchain.cys.mapper.CarDriverMapper;
import com.coldchain.cys.service.ICarDriverService;
import com.coldchain.cys.service.ICarService;
import com.coldchain.message.MessageUtils;
import com.coldchain.message.core.constant.MessageType;
import com.coldchain.message.core.entity.Message;
import com.coldchain.message.core.entity.SMSMsg;
import com.fangliai.core.base.service.impl.BaseServiceImpl;
import com.fangliai.core.context.BaseContextHandler;
import com.fangliai.core.entitiy.BaseSearch;
import com.fangliai.core.entitiy.PageResponse;
import com.fangliai.core.entitiy.SystemModelEnum;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author tianpeng
 * @since 2018-08-28
 */
@Service
public class CarDriverServiceImpl extends BaseServiceImpl<CarDriverMapper, CarDriver> implements ICarDriverService {
	private static final Logger log= LoggerFactory.getLogger(CarDriverServiceImpl.class);
	@Autowired
	private CarDriverMapper carDriverMapper ;
	
	@Autowired
	private ICarService carService ;
	
	@Autowired
	private MessageUtils messageUtils ; 
	@Autowired
	private RedisUtils redisUtils;
	
	@Override
	public List<CarDriver> getListByIds(String carDriverList) {
		Long[] carDriverIds = Convert.toLongArray(carDriverList);

		return (List<CarDriver>) super.listByIds(CollUtil.newArrayList(carDriverIds));
	}

	@Override
	public List<CarDriver> getListByIds(String carDriverList, Long cysId) {
		Long[] carDriverIds = Convert.toLongArray(carDriverList);
		List<Long> carDriverIdArray = CollUtil.newArrayList(carDriverIds);

		QueryWrapper<CarDriver> ew = new QueryWrapper<CarDriver>();
		ew.eq("cid", cysId) ;
		ew.in("id", carDriverIdArray) ;
		return super.list(ew) ;
	}


	@Override
	public CarDriver getCarDriverInfo(Long id) {
		CarDriver carDriver = super.getById(id);
		if(carDriver!=null){
			carDriver.setCar(carService.getById(carDriver.getCarid()));
		}
		return carDriver ;
	}

	@Transactional
	@Override
	public BaseResponse edit(CarDriver carDriver) {
		Long cysId = CysContext.getCysID();

		String sysModel = BaseContextHandler.getSysModl();
		try {
			ValidatorUtils.validateEntity(carDriver);
		} catch (Exception e) {
			log.error("表单参数证码失败,{}",e.getMessage());
			return new ObjectRestResponse<>().error("参数错误");
		}
		if(StringUtils.isEmpty(carDriver.getDriverId())){
			carDriver.setCid(BaseContextHandler.getCysID()); //设置承运商id
			carDriver.setCreatetime(new Date());
			carDriver.setPassword(MD5Utils.getMD5Str(Constant.DEFAULT_PASSWORD));
		}
		try{
			boolean result = super.saveOrUpdate(carDriver);
			if(!result){
				return new ObjectRestResponse<>().error("编辑失败");
			}
		}catch (Exception e){
			log.error("add driver error:{}",e.getMessage());
			return new ObjectRestResponse<>().succeed("服务器异常") ;
		}
		return new ObjectRestResponse<>().succeed("操作成功") ;
	}

	@Override
	public BaseResponse validateCarDriverLogin(String username,String password) {
		if(StrUtil.isBlank(username)){
			return new ObjectRestResponse<>().error("账号不能为空") ;
		}
		if(StrUtil.isBlank(password)){
			return new ObjectRestResponse<>().error("密码不能为空") ;
		}
		CarDriver cd = getByPhone(username);
		if(cd == null){
			return new ObjectRestResponse<>().error("账号或者密码错误") ;
		}
		try{
			validateCarDriver(cd.getDriverId());
		}catch (Exception e){
			return new ObjectRestResponse<>().error(e.getMessage()) ;
		}
		String md5Password = MD5Utils.getMD5Str(password);
		if(!cd.getPassword().equals(md5Password)){
			return new ObjectRestResponse<>().error("密码错误");
		}
		AuthUser authUser=new AuthUser();
		authUser.setUserId(cd.getDriverId());

		authUser.setUserName(cd.getPhone());
		authUser.setNickName(cd.getName());
		authUser.setCysId(cd.getCid());
		return new ObjectRestResponse<AuthUser>().data(authUser);
	}

	@Override
	public CarDriver getByPhone(String phone) {
		QueryWrapper<CarDriver> ew = new QueryWrapper<CarDriver>();
		ew.eq("phone", phone) ;
		return super.getOne(ew) ;
	}

	@Override
	public CarDriver getCurrent() {
		return super.getById(BaseContextHandler.getUserID()) ;
	}

	@Override
	public boolean validateCarDriver(String carDriverId) throws Exception{
		CarDriver cd = super.getById(carDriverId) ;
		if(cd.getIsdel() == Constant.LOGIC_DELETE){
			throw  new Exception("找不到数据");
		}
		if(cd.getIsuse() == Constant.DISABLE_USE){
			throw new Exception("该用户状态异常");
		}
		if(cd.getStatus() != Constant.CAR_DRIVER_EXAMINE_SUCCESS){
			throw new Exception("该用户正在审核中");
		}
		return true;
	}

	@Transactional
	@Override
	public BaseResponse doExamineCarDriver(Long driverid, Integer status) {
		if(driverid == null){
			return getErrorResult("driverid是必填的") ;
		}
		if(status == null){
			return getErrorResult("status是必填的") ;
		}
		String sysModel = BaseContextHandler.getSysModl();
		if(!sysModel.equals(SystemModelEnum.ADMIN.name())){
			return getErrorResult("无权操作") ;
		}
		if(status != 1 && status != 2){
			return getErrorResult("审核的状态必须是1或者2") ;
		}
		CarDriver carDriver = super.getById(driverid);
		carDriver.setStatus(status);
		super.updateById(carDriver) ;
		return new ObjectRestResponse<>().succeed("操作成功") ;
	}

	private BaseResponse getErrorResult(String msg){
		return new ObjectRestResponse<>().error(msg) ;
	}

	@Transactional
	@Override
	public BaseResponse doSwitchCarDriverUse(Long driverid) {
		if(driverid == null){
			return getErrorResult("driverid是必填项") ;
		}
		CarDriver carDriver = super.getById(driverid);
		if(carDriver == null){
			return getErrorResult("司机不存在") ;
		}
		String sysModel = BaseContextHandler.getSysModl();
		if(sysModel.equals(SystemModelEnum.CYS.name())){
			//承运商
			Long cysid = CysContext.getCysID();
			if(!carDriver.getCid().equals(cysid)){
				return getErrorResult("无权操作") ;
			}
		}
		if(sysModel.equals(SystemModelEnum.USER.name()) || sysModel.equals(SystemModelEnum.DRIVER.name())){
			return getErrorResult("无权操作") ;
		}
		if(carDriver.getIsuse() == Constant.ENABLE_USE){
			carDriver.setIsuse(Constant.DISABLE_USE);
		}else{
			carDriver.setIsuse(Constant.ENABLE_USE);
		}
		super.updateById(carDriver);
		return new ObjectRestResponse<>().succeed("操作成功") ;
	}

	@Override
	public List<CarDriver> getNotCarList(String search) {
		Long cysId = CysContext.getCysID();
		QueryWrapper<CarDriver> ew = new QueryWrapper<CarDriver>();
		ew.isNull("carid") ; //比赛是没有绑定车辆的司机
		ew.eq("cid", cysId) ; //必须是该承运商的
		ew.eq("static",1) ; //必须是审核通过
		if(StrUtil.isNotEmpty(search)) {
			ew.and(i -> i.like("name", search).or().like("phone", search)) ;
		}
		return super.list(ew) ;
	}

	@Transactional
	@Override
	public boolean updateCarid(CarDriver originCarDriver) {
		if(originCarDriver == null) {
			return false ; 
		}
		if(StringUtils.isEmpty(originCarDriver.getDriverId())){
			return false ;
		}
		boolean flag = carDriverMapper.updateCarid(originCarDriver);
		return flag ;
	}

	@Transactional
	@Override
	public BaseResponse doSaveCarDriverInfo(String name, String headImage) {
		if(StrUtil.isBlank(name)) {
			return getErrorResult("姓名不能为空") ;
		}
		if(StrUtil.isBlank(headImage)) {
			return getErrorResult("必须上传头像") ;
		}
		String carDriverId = BaseContextHandler.getUserID(); //司机的id
		CarDriver carDriver = new CarDriver();
		carDriver.setDriverId(carDriverId);
		carDriver.setName(name);
		carDriver.setHeadImage(headImage);
		boolean result = super.updateById(carDriver);
		if(!result) {
			return getErrorResult("操作失败") ;
		}
		return getErrorResult("保存成功") ;
	}

	@Transactional
	@Override
	public BaseResponse doSwitchCarDriverAutoReceive() {
		CarDriver carDriver = getCurrent();
		if(carDriver == null) {
			return getErrorResult("请先登录") ;
		}
		if(carDriver.getAutoReceive() == Constant.CAR_DRIVER_OFF_AUTO_RECEIVE) {
			carDriver.setAutoReceive(Constant.CAR_DRIVER_ON_AUTO_RECEIVE); 
		}else {
			carDriver.setAutoReceive(Constant.CAR_DRIVER_OFF_AUTO_RECEIVE);
		}
		boolean result = super.updateById(carDriver);
		if(!result) {
			return getErrorResult("操作失败") ;
		}
		return new ObjectRestResponse<>().succeed("更改成功") ;
	}

	@Transactional
	@Override
	public BaseResponse doSwitchCarDriverVoiceNotice() {
		CarDriver carDriver = getCurrent();
		if(carDriver == null) {
			return getErrorResult("请先登录") ;
		}
		if(carDriver.getVoiceNotice() == Constant.CAR_DRIVER_OFF_VOICE_NOTICE) {
			carDriver.setVoiceNotice(Constant.CAR_DRIVER_ON_VOICE_NOTICE); 
		}else {
			carDriver.setVoiceNotice(Constant.CAR_DRIVER_OFF_VOICE_NOTICE);
		}
		boolean result = super.updateById(carDriver);
		if(!result) {
			return getErrorResult("操作失败") ;
		}
		return new ObjectRestResponse<>().succeed("更改成功") ;
	}

	@Override
	public BaseResponse doSetReceiveTime(String worktimeBegin, String worktimeEnd) {
		CarDriver carDriver = getCurrent();
		if(carDriver == null) {
			return getErrorResult("请先登录") ;
		}
		if(StrUtil.isEmpty(worktimeBegin)) {
			return getErrorResult("接单开始时间不能为空") ;
		}
		boolean validateResult = ReUtil.isMatch("\\d{2}:\\d{2}", worktimeBegin);
		if(!validateResult) {
			return getErrorResult("接单开始时间格式不正确") ;
		}
		if(StrUtil.isEmpty(worktimeEnd)) {
			return getErrorResult("接单结束时间不能为空") ;
		}
		validateResult = ReUtil.isMatch("\\d{2}:\\d{2}", worktimeEnd) ;
		if(!validateResult) {
			return getErrorResult("接单结束时间格式不正确") ;
		}
		carDriver.setWorktimeBegin(worktimeBegin);
		carDriver.setWorktimeEnd(worktimeEnd);
		return new ObjectRestResponse<>().succeed("设置成功") ;
	}

	@Transactional
	@Override
	public BaseResponse doIncrementSuccessOrder(Long driverid) {
		CarDriver driver = super.getById(driverid);
		if(driver == null) {
			return getErrorResult("司机不存在") ;
		}
		driver.setAchievement(driver.getAchievement() + 1);
		boolean result = super.updateById(driver);
		if(!result) {
			return getErrorResult("操作失败") ;
		}
		return new ObjectRestResponse<>().succeed("操作成功") ;
	}

	@Transactional
	@Override
	public BaseResponse doIncrementRetreatOrder(Long driverid) {
		CarDriver driver = super.getById(driverid);
		if(driver == null) {
			return getErrorResult("司机不存在") ;
		}
		driver.setRefund(driver.getRefund() + 1);
		boolean result = super.updateById(driver);
		if(!result) {
			return getErrorResult("操作失败") ;
		}
		return new ObjectRestResponse<>().succeed("操作成功") ;
	}
	
	
	@Override
	public BaseResponse doSendLoginValidate(String phone) {
		if(StrUtil.isBlank(phone)) {
			return getErrorResult("发送失败") ;
		}
		CarDriver carDriver = getByPhone(phone);
		if(carDriver == null) {
			return getErrorResult("该司机不存在") ;
		}
		String code = RandomUtil.createSixValicode() ; //这里填写短信验证码
		SMSMsg sms=new SMSMsg(phone,code);
		messageUtils.sendSMSMsg(new Message<SMSMsg>(sms,MessageType.SMS_MSG));
		redisUtils.getRMapCache("code").put(phone, code, 5, TimeUnit.MINUTES) ; //存入redis 验证码
		return new ObjectRestResponse<>("操作成功") ;
	}

	@Override
	public BaseResponse validateCarDriverCodeLogin(String phone, String code) {
		if(StrUtil.isEmpty(phone)) {
			return getErrorResult("手机号码不能为空") ;
		}
		if(StrUtil.isEmpty(code)) {
			return getErrorResult("短信验证码不能为空") ;
		}
		CarDriver carDriver = getByPhone(phone);
		if(carDriver == null) {
			return getErrorResult("司机不存在") ;
		}
		String validateCode = (String) redisUtils.getRMapCache("code").get(phone);
		if(StrUtil.isEmpty(validateCode)) {
			return getErrorResult("短信验证码错误") ; 
		}
		if(!validateCode.equals(code)) {
			return getErrorResult("短信验证码错误") ;
		}
		redisUtils.getRMapCache("code").fastRemoveAsync(phone) ; //删除
		
		AuthUser authUser=new AuthUser();
		authUser.setUserId(carDriver.getDriverId());
		authUser.setUserName(carDriver.getPhone());
		authUser.setNickName(carDriver.getName());
		authUser.setCysId(carDriver.getCid().toString());
		
		return new ObjectRestResponse<AuthUser>().data(authUser);
	}

	@Override
	public BaseResponse doSendForgetValidate(String phone) {
		if(StrUtil.isBlank(phone)) {
			return getErrorResult("发送失败") ;
		}
		CarDriver carDriver = getByPhone(phone);
		if(carDriver == null) {
			return getErrorResult("该司机不存在") ;
		}
		String code = RandomUtil.createSixValicode() ; //这里填写短信验证码
		SMSMsg sms=new SMSMsg(phone,code);
		messageUtils.sendSMSMsg(new Message<SMSMsg>(sms,MessageType.SMS_MSG));
		redisUtils.getRMapCache("forget").put(phone, code, 5, TimeUnit.MINUTES) ; //存入redis 验证码
		return new ObjectRestResponse<>("操作成功") ;
	}

	
	@Override
	public BaseResponse validateCarDriverForget(String phone, String code) {
		if(StrUtil.isBlank(phone)) {
			return getErrorResult("参数错误") ;
		}
		if(StrUtil.isBlank(code)) {
			return getErrorResult("参数错误") ;
		}
		CarDriver carDriver = getByPhone(phone);
		if(carDriver == null) {
			return getErrorResult("司机不存在") ;
		}
		String validateCode = (String) redisUtils.getRMapCache("forget").get(phone);
		if(StrUtil.isBlank(validateCode)) {
			return getErrorResult("短信验证码错误") ;
		}
		if(!code.equals(validateCode)) {
			return getErrorResult("短信验证码错误") ;
		}
		redisUtils.getRMapCache("forget").fastRemoveAsync(phone) ; //删除
		String str = carDriver.getPhone() + "," + carDriver.getPassword() ;
		String token = null;
		try {
			token = DesUtil.encrypt(str);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return new ObjectRestResponse<>().succeed(token);
	}

	@Transactional
	@Override
	public BaseResponse doDriverChangeForgetPass(String token, String newPass) {
		if(StrUtil.isBlank(token)) {
			return getErrorResult("参数错误") ;
		}
		if(StrUtil.isBlank(newPass)) {
			return getErrorResult("参数错误") ;
		}
		String str = null ;
		try {
			str = DesUtil.decrypt(token);
		} catch (Exception e) {
			e.printStackTrace();
		}
		if(StrUtil.isBlank(str)) {
			return getErrorResult("参数错误") ;
		}
		String[] strArray = str.split(",");
		CarDriver carDriver = getByPhone(strArray[0]);
		if(carDriver == null) {
			return getErrorResult("参数错误") ;
		}
		if(!carDriver.getPassword().equals(strArray[1])) {
			return getErrorResult("参数错误") ;
		}
		String enPass = MD5Utils.getMD5Str(newPass);
		carDriver.setPassword(enPass);
		boolean result = super.updateById(carDriver);
		if(!result) {
			return getErrorResult("操作失败") ;
		}
		return new ObjectRestResponse<>().succeed("修改成功") ;
	}

	@Override
	public int countByCarDriver(CarDriver carDriver) {
		Long cysId = CysContext.getCysID();
		QueryWrapper<CarDriver> ew = new QueryWrapper<CarDriver>();
		ew.eq("cid", cysId) ;
		if(carDriver.getStatus() != null) {
			ew.eq("static", carDriver.getStatus()) ;
		}
		if(carDriver.getWorkstatus() != null) {
			ew.eq("workstatus", carDriver.getWorkstatus()) ;
		}
		return super.count(ew) ;
	}

	@Override
	public Integer sumAchievement() {
		Long cysId = CysContext.getCysID();
		QueryWrapper<CarDriver> ew = new QueryWrapper<CarDriver>();
		ew.select("IFNULL(SUM(achievement),0) AS achievementTotal") ;
		ew.eq("cid", cysId) ;
		Map<String, Object> result = super.getMap(ew);
		if(result != null && result.size() > 0) {
			return ((BigDecimal) result.get("achievementTotal")).intValue() ;
		}
		return 0 ; 
	}

	@Override
	public Integer sumRefund() {
		Long cysId = CysContext.getCysID();
		QueryWrapper<CarDriver> ew = new QueryWrapper<CarDriver>();
		ew.select("IFNULL(SUM(refund),0) AS refundTotal") ;
		ew.eq("cid", cysId) ;
		Map<String, Object> result = super.getMap(ew);
		if(result != null && result.size() > 0) {
			return ((BigDecimal) result.get("refundTotal")).intValue() ;
		}
		return 0 ; 
	}

	@Override
	public PageResponse<CarDriver> search(BaseSearch<CarDriver> search) {
		PageResponse<CarDriver> pageResponse=super.search(search);
		pageResponse.getRecords().forEach((v->{
			 v.setCar(carService.getById(v.getCarid()));
		}));
		return pageResponse;
	}

	@Override
	public List<CarDriver> searchForList(BaseSearch<CarDriver> search) {
		List<CarDriver> carDrivers=super.searchForList(search);
		carDrivers.forEach((v->{
			v.setCar(carService.getById(v.getCarid()));
		}));
		return carDrivers;
	}
}
